#ifndef __K2OS_PRIVATE_H
#define __K2OS_PRIVATE_H
#include "port.h"
#include "k2os_config.h"

/**
 *************************************************************************************
 *                          system internal cfg macro
 * ***********************************************************************************
 */

/**
 * @brief number of system tasks
 * 
 */
#define OS_SYSTEM_TASKS_NUM                             (2)    

/**
 * @brief size of task ready table 
 * 
 */
#define OS_CFG_TASK_READY_TBL_SIZE                      (8)     

/**
 * @brief the lowest task's priority
 * @attention:  do not change the config
 */
#define OS_CFG_TASK_PRIORITY_LOWEST                     (63)   

/**
 * @brief system idle task's stack size
 * 
 */
#define OS_CFG_IDLE_TASK_STACK_SIZE                     (64)


/**
 *************************************************************************************
 *                          extern global variable
 *************************************************************************************
 */
extern u8_t                        k2os_isr_nesting;   



/**
 *************************************************************************************
 *                          list function
 *************************************************************************************
 */

/**
 * @brief get offset of a member variable
 * 
 * @param[in]   type    the type of the struct this is embeded in.
 * @param[in]   member  the name of variable wiithin the struct.
 */
/*
#define k2os_offsetof(type, member)          ((os_size_t)&(((type *)0)->member)) 
*/

/**
 * @brief get the struct for this entry
 * 
 * @param[in]   ptr     the list head to take the element from
 * @param[in]   type    the type of the struct this is embedded in.
 * @param[in]   member  the name of the variable within the struct.
 */
/*
#define k2os_container_of(ptr, type, member) \
    ((type *) ((char *) (ptr) - k2os_offsetof(type, member)))


typedef struct slist_s{
    struct slist_s *next;
} slist_t;


static __inline void slist_add(slist_t *node, slist_t *head)
{
    node->next = head->next;
    head->next = node;
}

static __inline void slist_add_tail(slist_t *node, slist_t *head)
{
    while(head->next){
        head = head->next;
    }
    slist_add(node, head);
}

static __inline void slist_del(slist_t *node, slist_t *head)
{
    while (head->next) {
        if (head->next == node) {
            head->next = node->next;
            break;
        }

        head = head->next;
    }
}

static __inline int slist_empty(slist_t *head)
{
    return !head->next;
}

static __inline void slist_init(slist_t *head)
{
    head->next = 0;
}
*/

/**
* Iterate over list of given type.
*
* @param[in]   queue   he head for your list.
* @param[in]   node    the type * to use as a loop cursor.
* @param[in]   type    the type of the struct this is embedded in.
* @param[in]   member  the name of the slist_t within the struct.
*/
/*
#define slist_for_each_entry(queue, node, type, member)        \
    for (node = k2os_container_of((queue)->next, type, member); \
         &node->member;                                        \
         node = k2os_container_of(node->member.next, type, member))
*/

/**
 * Iterate over list of given type safe against removal of list entry.
 *
 * @param[in]   queue   the head for your list.
 * @param[in]   tmp     the type * to use as a temp.
 * @param[in]   node    the type * to use as a loop cursor.
 * @param[in]   type    the type of the struct this is embedded in.
 * @param[in]   member  the name of the slist_t within the struct.
 */
/*
#define slist_for_each_entry_safe(queue, tmp, node, type, member) \
    for (node = k2os_container_of((queue)->next, type, member),    \
         tmp = (queue)->next ? (queue)->next->next : NULL;        \
         &node->member;                                           \
         node = k2os_container_of(tmp, type, member), tmp = tmp ? tmp->next : tmp)
*/

/**
 * Get the struct for this entry.
 * @param[in]   addr     the list head to take the element from.
 * @param[in]   type     the type of the struct this is embedded in.
 * @param[in]   member   the name of the slist_t within the struct.
 */
/*
#define slist_entry(addr, type, member) (                                   \
        addr ? (type *)((long)addr - k2os_offsetof(type, member)) : (type *)addr \
                                        )
*/

/**
* Get the first element from a list.
*
* @param[in]   ptr     the list head to take the element from.
* @param[in]   type    the type of the struct this is embedded in.
* @param[in]   member  the name of the slist_t within the struct.
*/
/*
#define slist_first_entry(ptr, type, member) \
    slist_entry((ptr)->next, type, member)
*/

/*
 * Get the list length.
 *
 * @param[in]   queue    the head for your list.
 */
/*
static __inline int slist_entry_number(slist_t *queue)
{
    int num;
    slist_t *cur = queue;
    for (num = 0; cur->next; cur = cur->next, num++)
        ;

    return num;
}
*/


/**
 *************************************************************************************
 *                         task control block define
 *************************************************************************************
 */
typedef struct os_tcb{
    volatile os_stk_t   *pTopOfStack;           /* pointer to top of task stack                         */
    u32_t               taskDlyTicks;           /* number ticks to delay task                           */
    u8_t                taskStatus;             /* task status                                          */
    u8_t                taskPriority;           /* task priority                                        */  
    u8_t                taskReadyTbl_bit;       /* task ready table bit  */
    u8_t                taskReadyGroup_bit;     /* task ready group bit  */
    u8_t                taskReadyTbl_mask;      /* task ready table mask value */
    u8_t                taskReadyGroup_mask;    /* task ready group mask value */
    
    struct os_tcb       *list_next_tcb;         /* pointer to next tcb */
} os_tcb_t;

/**
 *************************************************************************************
 *                         task control block heap
 *************************************************************************************
 */
#define OS_FLAG_UNUSED           (0)
#define OS_FLAG_USED             (1)
typedef struct os_tcb_heap{
    u8_t        flag_used;              /* flag of heap used or unused */
    os_tcb_t    tcb;                    /* tcb memory*/
} os_tcb_heap_t;

/**
 *************************************************************************************
 *                         task priority info define
 *************************************************************************************
 */
typedef struct os_task_priority_info{
    os_tcb_t    *ptcb;                          /* point to the priority of task's tcb */
} os_task_priority_info_t;


/**
 *************************************************************************************
 *                         task status enum
 *************************************************************************************
 */
typedef enum{
    OS_TASK_STATUS_READY = 0,
    OS_TASK_STATUS_SLEEPING,
    OS_TASK_STATUS_RUNNING
} os_task_status_t;







#endif
